package org.example.ref;

import java.io.*;
import java.net.Socket;
import java.nio.charset.Charset;
import java.util.Random;

/**
 * Hello world!
 */
public class App2 {
    public static void main(String[] args) throws Exception {
        // 连接 FTP 服务器
        Socket socket = new Socket("127.0.0.1", 21);

        OutputStream os = socket.getOutputStream();
        InputStream is = socket.getInputStream();
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));

        // 连接成功的消息
        String msg;
        do {
            msg = reader.readLine();
            System.out.println(msg);
        } while (!msg.startsWith("220"));

        // 登录
        os.write("USER fyx\r\n".getBytes(Charset.defaultCharset()));
        os.write("PASS 123456\r\n".getBytes(Charset.defaultCharset()));
        do {
            msg = reader.readLine();
            System.out.println(msg);
        } while (!msg.startsWith("230"));

        // 让服务器进入被动模式
        /*
        当客户端在下载/上传文件前，要先发送命令让服务器进入被动模式。服务器会打开数据端口并监听。并返回响应码 227 和数据连接的端口号。
         */
//        os.write("PASV\r\n".getBytes(Charset.defaultCharset()));
//        do {
//            msg = reader.readLine();
//            System.out.println(msg);
//        } while (!msg.startsWith("227"));




/*       //上传文件
        // 解析被动模式返回的端口信息
        String[] parts = msg.split("[()]")[1].split(",");
        String ip = String.join(".", parts[0], parts[1], parts[2], parts[3]);
        int port = (Integer.parseInt(parts[4]) * 256) + Integer.parseInt(parts[5]);

        // 创建数据连接的 Socket
        Socket dataSocket = new Socket(ip, port);
        OutputStream dataOs = dataSocket.getOutputStream();

        // 上传文件
        File file = new File("1.txt");
        os.write(("STOR " + file.getName() + "\r\n").getBytes(Charset.defaultCharset()));
        do {
            msg = reader.readLine();
            System.out.println(msg);
        } while (!msg.startsWith("150"));

        byte[] bytes = new byte[1024];
        FileInputStream fis = new FileInputStream(file);
        int bytesRead;
        while ((bytesRead = fis.read(bytes)) != -1) {
            dataOs.write(bytes, 0, bytesRead);
        }
        fis.close();
        dataOs.flush();
        dataOs.close();
        dataSocket.close();

        // 接收上传完成的消息
        do {
            msg = reader.readLine();
            System.out.println(msg);
        } while (!msg.startsWith("226"));*/


        // 尝试使用被动模式下载文件
        try {
            // 让服务器进入被动模式
            os.write("PASV\r\n".getBytes(Charset.defaultCharset()));
            String pasvResponse;
            do {
                pasvResponse = reader.readLine();
                System.out.println(pasvResponse);
            } while (!pasvResponse.startsWith("227"));

            // 解析被动模式返回的端口信息
            String[] parts = pasvResponse.split("[()]")[1].split(",");
            String ip = String.join(".", parts[0], parts[1], parts[2], parts[3]);
            int port = (Integer.parseInt(parts[4]) * 256) + Integer.parseInt(parts[5]);

            System.out.println("Connecting to data IP: " + ip + " Port: " + port);

            // 创建数据连接的 Socket
            Socket dataSocket = new Socket(ip, port);
            InputStream dataIs = dataSocket.getInputStream();

            // 下载文件
            os.write("RETR Java logo.png\r\n".getBytes(Charset.defaultCharset()));
            do {
                msg = reader.readLine();
                System.out.println(msg);
            } while (!msg.startsWith("150"));

            FileOutputStream fos = new FileOutputStream("Java logo.png");
            byte[] bytes = new byte[1024];
            int bytesRead;
            while ((bytesRead = dataIs.read(bytes)) != -1) {
                fos.write(bytes, 0, bytesRead);
            }
            fos.close();
            dataIs.close();
            dataSocket.close();

            // 接收下载完成的消息
            do {
                msg = reader.readLine();
                System.out.println(msg);
            } while (!msg.startsWith("226"));
        } catch (Exception e) {
            System.err.println("Passive mode failed, trying active mode...");
            e.printStackTrace();

            // TODO: 2024/6/12 没有封装到 EasyFTP
            // 使用主动模式下载文件
            Random random = new Random();
            int localPort = 1025 + random.nextInt(64510); // 随机选择一个1025到65535之间的端口
            Socket activeDataSocket = new Socket(socket.getLocalAddress(), localPort);
            os.write(("PORT " + socket.getLocalAddress().getHostAddress().replace('.', ',') + "," +
                    (localPort / 256) + "," + (localPort % 256) + "\r\n").getBytes(Charset.defaultCharset()));

            do {
                msg = reader.readLine();
                System.out.println(msg);
            } while (!msg.startsWith("200"));

            os.write("RETR 1.txt\r\n".getBytes(Charset.defaultCharset()));
            do {
                msg = reader.readLine();
                System.out.println(msg);
            } while (!msg.startsWith("150"));

            InputStream activeDataIs = activeDataSocket.getInputStream();
            FileOutputStream fos = new FileOutputStream("downloaded-1.txt");
            byte[] bytes = new byte[1024];
            int bytesRead;
            while ((bytesRead = activeDataIs.read(bytes)) != -1) {
                fos.write(bytes, 0, bytesRead);
            }
            fos.close();
            activeDataIs.close();
            activeDataSocket.close();

            // 接收下载完成的消息
            do {
                msg = reader.readLine();
                System.out.println(msg);
            } while (!msg.startsWith("226"));
        }

        socket.close();
    }
}
